﻿/**
 * @file std_list.inl
 * Copyright (c) 2019 Gaaagaa. All rights reserved.
 * 
 * @author  : Gaaagaa
 * @date    : 2019-09-09
 * @version : 1.0.0.0
 * @brief   : 定义 链表容器 内部相关数据类型、常量、宏 等。
 */

/**
 * The MIT License (MIT)
 * Copyright (c) Gaaagaa. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef __STD_LIST_INL__
#define __STD_LIST_INL__

#ifndef __STD_LIST_H__
#error "Please include std_list.h before this file."
#endif // __STD_LIST_H__

#include "std_comm.inl"

////////////////////////////////////////////////////////////////////////////////
// xstd_list_t 的相关数据定义

#if (XSTD_DEBUG_LEVEL >= XSTD_DEBUG_LOWER)
/** 便于进行代码调试时，是否可检测所属对象 */
#define XLST_CHECKED_OWNER    1
#else // !(XSTD_DEBUG_LEVEL >= XSTD_DEBUG_LOWER)
/** 便于进行代码调试时，是否可检测所属对象 */
#define XLST_CHECKED_OWNER    0
#endif // (XSTD_DEBUG_LEVEL >= XSTD_DEBUG_LOWER)

/** 所存储的元素数据缓存 是否与 节点缓存 分离 */
#define XLST_ELEM_SEPARATED   0

/**
 * @struct xlst_node_t
 * @brief  xstd_list_t 所使用的节点结构体描述信息。
 */
typedef struct xlst_node_t
{
    xlst_iter_t    xiter_prev;     ///< 串接前置节点的迭代器
    xlst_iter_t    xiter_next;     ///< 串接后置节点的迭代器
#if XLST_CHECKED_OWNER
    xlst_this_t  xlst_owner;     ///< 节点所属链表对象
#endif // XLST_CHECKED_OWNER

#if XLST_ELEM_SEPARATED

    xlst_elem_t    xlst_emptr;     ///< 节点所存储的元素对象缓存

#else // !XLST_ELEM_SEPARATED

#ifdef _MSC_VER
#pragma warning(disable:4200)
#endif // _MSC_VER
    xstd_byte_t    xlst_emptr[0];  ///< 节点所存储的元素对象缓存
#ifdef _MSC_VER
#pragma warning(default:4200)
#endif // _MSC_VER

#endif // XLST_ELEM_SEPARATED

} xlst_node_t;

/**
 * @struct xstd_list_t
 * @brief  双向链表容器的结构体描述信息。
 */
typedef struct xstd_list_t
{
    xstd_context_t  xstd_ectxt;  ///< 链表的节点类型上下文信息
    xlst_size_t     xlst_csize;  ///< 链表的节点数量

    /** 指向链表首尾端的节点指针 */
    struct
    {
    xlst_iter_t     xiter_prev;  ///< 串接前置节点的迭代器
    xlst_iter_t     xiter_next;  ///< 串接后置节点的迭代器
#if XLST_CHECKED_OWNER
    xlst_this_t     xlst_owner;  ///< 指向 自身
#endif // XLST_CHECKED_OWNER
    } xlst_entry;
} xstd_list_t;

////////////////////////////////////////////////////////////////////////////////
// xstd_list_t 的相关操作宏函数

//====================================================================

#define XLST_ECTXT(xlst_this)   XSTD_ECTXT(xlst_this)
#define XLST_ETYPE(xlst_this)   XSTD_ETYPE(xlst_this)
#define XLST_ESIZE(xlst_this)   XSTD_ESIZE(xlst_this)
#define XLST_ALTOR(xlst_this)   XSTD_ALTOR(xlst_this)

#define XLST_MALLOC(xlst_this, xst_size)            \
            XSTD_MALLOC((xlst_this), (xst_size))

#define XLST_DEALLOC(xlst_this, xmt_mptr)           \
            XSTD_DEALLOC((xlst_this), (xmt_mptr))

#define XLST_ALFROM(xlst_this, xet_dptr, xet_sptr)  \
            XSTD_ALFROM((xlst_this), (xet_dptr), (xet_sptr))

#define XLST_ALMOVE(xlst_this, xet_dptr, xet_sptr)  \
            XSTD_ALMOVE((xlst_this), (xet_dptr), (xet_sptr))

#define XLST_ALDEST(xlst_this, xet_elem)            \
            XSTD_ALDEST((xlst_this), (xet_elem))

#define XLST_ISSAME_TYPE(xlst_lthis, xlst_rthis)    \
            XSTD_ISSAME_TYPE((xlst_lthis), (xlst_rthis))

#define XLST_ECTXT_UPDATE(xlst_this, xlst_ctxt)     \
            XSTD_ECTXT_UPDATE((xlst_this), (xlst_ctxt))

//====================================================================

#define XLST_MAX_SIZE(xlst_this)  \
    ((xlst_size_t)(((xlst_size_t)~0) / XLST_ESIZE(xlst_this)))

#define XLST_RESET_ENTRY(xlst_this)                \
    do                                             \
    {                                              \
        (xlst_this)->xlst_entry.xiter_prev =       \
            (xlst_iter_t)&(xlst_this)->xlst_entry; \
        (xlst_this)->xlst_entry.xiter_next =       \
            (xlst_iter_t)&(xlst_this)->xlst_entry; \
    } while (0)

#define XLST_ITER_BEGIN(xlst_this)  ((xlst_this)->xlst_entry.xiter_next)
#define XLST_ITER_END(xlst_this)    ((xlst_iter_t)&(xlst_this)->xlst_entry)
#define XLST_ITER_RBEGIN(xlst_this) ((xlst_this)->xlst_entry.xiter_prev)
#define XLST_ITER_REND(xlst_this)   ((xlst_iter_t)&(xlst_this)->xlst_entry)

#define XLST_ITER_ELEM(xlst_iter)   ((xlst_elem_t)(xlst_iter)->xlst_emptr)

#define XLST_ITER_INSERT(xlst_iter, xlst_node)             \
    do                                                     \
    {                                                      \
        (xlst_node)->xiter_prev = (xlst_iter)->xiter_prev; \
        (xlst_node)->xiter_next = (xlst_iter);             \
        (xlst_iter)->xiter_prev = (xlst_node);             \
        (xlst_node)->xiter_prev->xiter_next = (xlst_node); \
    } while (0)

#define XLST_ITER_RMNODE(xlst_iter)                                \
    do                                                             \
    {                                                              \
        xlst_iter->xiter_prev->xiter_next = xlst_iter->xiter_next; \
        xlst_iter->xiter_next->xiter_prev = xlst_iter->xiter_prev; \
    } while (0)

#define XLST_ITER_UNDOCK(xlst_iter)                                \
    do                                                             \
    {                                                              \
        xlst_iter->xiter_prev->xiter_next = xlst_iter->xiter_next; \
        xlst_iter->xiter_next->xiter_prev = xlst_iter->xiter_prev; \
        xlst_iter->xiter_prev = XLST_NULL;                         \
        xlst_iter->xiter_next = XLST_NULL;                         \
    } while (0)

#define XLST_ITER_ISDOCK(xlst_iter)            \
    ((XLST_NULL != (xlst_iter)->xiter_prev) && \
     (XLST_NULL != (xlst_iter)->xiter_next))

#define XLST_ITER_SPLICE(xiter_pos, xiter_first, xiter_last, xiter_swap) \
    do                                                                   \
    {                                                                    \
        xiter_swap = xiter_last->xiter_prev;                             \
        xiter_first->xiter_prev->xiter_next = xiter_last;                \
        xiter_last->xiter_prev = xiter_first->xiter_prev;                \
        xiter_pos->xiter_prev->xiter_next = xiter_first;                 \
        xiter_first->xiter_prev = xiter_pos->xiter_prev;                 \
        xiter_pos->xiter_prev = xiter_swap;                              \
        xiter_swap->xiter_next = xiter_pos;                              \
    } while (0)

//====================================================================

////////////////////////////////////////////////////////////////////////////////

#endif // __STD_LIST_INL__
